home *** CD-ROM | disk | FTP | other *** search
/ Fritz: All Fritz / All Fritz.zip / All Fritz / FILES / COMMADIO / VT100102.LZH / XMODSYSV.ZIP / UMODEM41.C < prev   
Text File  |  1987-01-09  |  51KB  |  1,310 lines

  1. /*
  2.  *  UMODEM Version 4.0
  3.  *
  4.  *  UMODEM -- Implements the "CP/M User's Group XMODEM" protocol, 
  5.  *            the TERM II File Transfer Protocol (FTP) Number 1,
  6.  *            and the TERM II File Transfer Protocol Number 4 for
  7.  *            packetized file up/downloading.    
  8.  *
  9.  *    Note: UNIX System-Dependent values are indicated by the string [SD]
  10.  *          in a comment field on the same line as the values.
  11.  *
  12.  *
  13.  *         -- Lauren Weinstein, 6/81
  14.  *         -- (Version 2.0) Modified for JHU/UNIX by Richard Conn, 8/1/81
  15.  *         -- Version 2.1 Mods by Richard Conn, 8/2/81
  16.  *              . File Size Included on Send Option
  17.  *         -- Version 2.2 Mods by Richard Conn, 8/2/81
  18.  *              . Log File Generation and Option Incorporated
  19.  *         -- Version 2.3 Mods by Richard Conn, 8/3/81
  20.  *              . TERM II FTP 1 Supported
  21.  *              . Error Log Reports Enhanced
  22.  *              . CAN Function Added to FTP 3
  23.  *              . 'd' Option Added to Delete umodem.log File before starting
  24.  *         -- Version 2.4 Mods by Richard Conn, 8/4/81
  25.  *              . 16K-extent sector number check error corrected
  26.  *              . Count of number of received sectors added
  27.  *         -- Version 2.5 Mods by Richard Conn, 8/5/81
  28.  *              . ARPA Net Flag added
  29.  *              . ARPA Net parameter ('a') added to command line
  30.  *              . ARPA Net BIS, BIE, BOS, BOE added
  31.  *              . ARPA Net FFH escape added
  32.  *         -- Version 2.6 Mods by Bennett Marks, 8/21/81 (Bucky @ CCA-UNIX)
  33.  *              . mods for UNIX V7 (Note: for JHU compilation define
  34.  *                the variable JHU  during 'cc'
  35.  *              . added 'mungmode' flag to protect from inadvertant
  36.  *                overwrite on file receive
  37.  *              . changed timeout handling prior to issuing checksum
  38.  *         -- Version 2.7 Mods by Richard Conn, 8/25/81 (rconn @ BRL)
  39.  *              . correct minor "ifndef" error in which ifndef had no arg
  40.  *              . restructured "ifdef" references so that other versions
  41.  *                of UNIX than Version 7 and JHU can be easily incorporated;
  42.  *                previous ifdef references were for JHU/not JHU;
  43.  *                to compile under Version 7 or JHU UNIX, the following
  44.  *                command lines are recommended:
  45.  *                      "cc umodem.c -o umodem -DVER7" for Version 7
  46.  *                      "cc -7 umodem.c -o umodem -DJHU" for JHU
  47.  *              . added 'y' file status display option; this option gives
  48.  *                the user an estimate of the size of the target file to
  49.  *                send from the UNIX system in terms of CP/M records (128
  50.  *                bytes) and Kbytes (1024 byte units)
  51.  *              . added '7' option which modifies the transmission protocols
  52.  *                for 7 significant bits rather than 8; modifies both FTP 1
  53.  *                and FTP 3
  54.  *         -- Version 2.8 Mods by Richard Conn, 8/28/81
  55.  *              . corrected system-dependent reference to TIOCSSCR (for
  56.  *                disabling page mode) and created the PAGEMODE flag which
  57.  *                is to be set to TRUE to enable this
  58.  *              . added -4 option which engages TERM II, FTP 4 (new release)
  59.  *         -- Version 2.9 Mods by Richard Conn, 9/1/81
  60.  *              . internal documentation on ARPA Net protocols expanded
  61.  *              . possible operator precedence problem with BITMASK corrected
  62.  *                by redundant parentheses
  63.  *         -- Version 3.0 Mods by Lauren Weinstein, 9/14/81
  64.  *              . fixed bug in PAGEMODE defines (removed PAGEMODE define
  65.  *                line; now should be compiled with "-DPAGEMODE" if
  66.  *                Page Mode is desired)
  67.  *              . included forward declaration of ttyname() to avoid problems
  68.  *                with newer V7 C compilers
  69.  *         -- Version 3.1 Mods by Lauren Weinstein, 4/17/82
  70.  *              . avoids sending extraneous last sector when file EOF
  71.  *                occurs on an exact sector boundary
  72.  *         -- Version 3.2 Mods by Michael M Rubenstein, 5/26/83
  73.  *              . fixed bug in readbyte.  assumed that int's are ordered
  74.  *                from low significance to high
  75.  *              . added LOGDEFAULT define to allow default logging to be
  76.  *                off.  compile with -DLOGDEFAULT=0 to set default to no
  77.  *                logging.
  78.  *         -- Version 3.3 Mod by Ben Goldfarb, 07/02/83
  79.  *              . Corrected problem with above implementation of "LOGDEFAULT".
  80.  *                A bitwise, instead of a logical negation operator was
  81.  *                used to complement LOGFLAG when the '-l' command line
  82.  *                flag was specified.  This can cause LOGFLAG to be true
  83.  *                when it should be false.
  84.  *         -- Version 3.4 Mods by David F. Hinnant, NCECS, 7/15/83
  85.  *              . placed log file in HOME directory in case user doesn't
  86.  *                have write permission in working directory.
  87.  *              . added DELDEFAULT define to allow default purge/no purge
  88.  *                of logfile before starting.  Compile with -DDELDEFAULT=0
  89.  *                to set default to NOT delete the log file before starting.
  90.  *              . check log file for sucessful fopen().
  91.  *              . buffer disk read for sfile().
  92.  *              . turn messages off (standard v7) before starting.
  93.  *         -- Version 3.5 Mods by Richard Conn, 08/27/83
  94.  *              . added equates for compilation under UNIX SYSTEM III
  95.  *                      to compile for SYSTEM III, use -DSYS3 instead of
  96.  *                      -DJHU or -DVER7
  97.  *              . added command mode (-c option) for continuous entry
  98.  *                      of commands
  99.  *          --  Version 4.0 Mods by Mycroft Holmes, 04/17/84
  100.  *                . released constraint on using caps for commands in
  101.  *                        the 'command' mode. 
  102.  *                . added descriptors for local mode, allowing use of
  103.  *                        environmental variable 'MODEM' to specify
  104.  *                        i/o port. now, no more limitation to remote
  105.  *                        usage only.
  106.  *                . added rudamentary terminal program for local mode
  107.  *                        and (ala modem7 series, thankyou
  108.  *                        WC) ^E exits terminal mode.  
  109.  *                . reassigned SIGINT to command() when in local mode, thus
  110.  *                        no die from program, just return to command mode.
  111.  *                . put the conditional (on local mode) display of sector
  112.  *                        counts (so you could see it work).
  113.  *                . made case conversions to lower case conditional on
  114.  *                        being upper case, instead of always.  thus using
  115.  *                        lower case in commands works.  (defined 'mklow')
  116.  *                . put in flag to search for in order to get past all this
  117.  *                        garbage at the start of the file.
  118.  *                . forced exit(0) on 'x' from command mode.
  119.  *         --  Version 4.1 Mods by Mike Slomin, 11/21/85
  120.  *          . made compatible with Xilog UNIX system
  121.  *          . but retains compatibility with System V
  122.  *          . commands made parity independent
  123.  *          . port busy routines added (for terminal mode)
  124.  *          . toggle 300/1200 terminal mode speed added
  125.  *          . spaces added to the packet no. print routines so that
  126.  *              each packet number fully overwrites the previous
  127.  *                 one (otherwise it's disconcerting!!)
  128.  *EOS
  129.  */
  130. #include <stdio.h>
  131. #include <sys/types.h>
  132. #include <sys/stat.h>
  133. #include <ctype.h>
  134. #define mklow(c) (isupper(c) ? tolower(c) : c)
  135.  
  136. #include <sgtty.h>
  137.  
  138. /* log default define */
  139. #ifndef LOGDEFAULT
  140. #define LOGDEFAULT      1
  141. #endif
  142.  
  143. /* Delete logfile define.  Useful on small systems with limited
  144.  * filesystem space and careless users.
  145.  */
  146. #ifndef DELDEFAULT
  147. #define DELDEFAULT      1
  148. #endif
  149.  
  150. #include <signal.h>
  151.  
  152. #define      VERSION    40      /* Version Number */
  153. #define      FALSE      0
  154. #define      TRUE       ~FALSE
  155.  
  156. /*  Compile with "-DPAGEMODE" if Page Mode (TIOCSSCR) is supported on your
  157.  *  UNIX system.  If it is supported, make sure that TIOCSSCR is the
  158.  *  correct name for Page Mode engagement.
  159.  */
  160.  
  161. /*  ASCII Constants  */
  162. #define      SOH        001 
  163. #define      STX        002
  164. #define      ETX        003
  165. #define      EOT        004
  166. #define      ENQ        005
  167. #define      ACK        006
  168. #define      LF         012   /* Unix LF/NL */
  169. #define      CR         015  
  170. #define      NAK        025
  171. #define      SYN        026
  172. #define      CAN        030
  173. #define      ESC        033
  174. #define      CTRLZ      032   /* CP/M EOF for text (usually!) */
  175. #define      ZERO       000   /* binary send pad character    */
  176.  
  177. /*  UMODEM Constants  */
  178. #define      TIMEOUT    -1
  179. #define      ERRORMAX   10    /* maximum errors tolerated */
  180. #define      RETRYMAX   10    /* maximum retries to be made */
  181. #define      BBUFSIZ    128   /* buffer size -- do not change! */
  182.  
  183. /*  [SD] Mode for Created Files  */
  184. #define      CREATMODE  0644  /* mode for created files */
  185.  
  186. /*  ARPA Net Constants  */
  187. /*      The following constants are used to communicate with the ARPA
  188.  *      Net SERVER TELNET and TIP programs.  These constants are defined
  189.  *      as follows:
  190.  *              IAC                     <-- Is A Command; indicates that
  191.  *                                              a command follows
  192.  *              WILL/WONT               <-- Command issued to SERVER TELNET
  193.  *                                              (Host); WILL issues command
  194.  *                                              and WONT issues negative of
  195.  *                                              the command
  196.  *              DO/DONT                 <-- Command issued to TIP; DO issues
  197.  *                                              command and DONT issues
  198.  *                                              negative of the command
  199.  *              TRBIN                   <-- Transmit Binary Command
  200.  *      Examples:
  201.  *              IAC WILL TRBIN  <-- Host is configured to transmit Binary
  202.  *              IAC WONT TRBIN  <-- Host is configured NOT to transmit binary
  203.  *              IAC DO TRBIN    <-- TIP is configured to transmit Binary
  204.  *              IAC DONT TRBIN  <-- TIP is configured NOT to transmit binary
  205.  */
  206. #define      IAC        0377    /* Is A Command */
  207. #define      DO         0375    /* Command to TIP */
  208. #define      DONT       0376    /* Negative of Command to TIP */
  209. #define      WILL       0373    /* Command to SERVER TELNET (Host) */
  210. #define      WONT       0374    /* Negative of Command to SERVER TELNET */
  211. #define      TRBIN      0       /* Transmit Binary Command */
  212.  
  213. struct sgttyb  ttys, ttysnew, ttystemp;    /* for stty terminal mode calls */
  214. struct sgttyb  ttycon, ttycom;
  215.  
  216. struct stat statbuf;    /* for terminal message on/off control */
  217. char *strcat();
  218. FILE *LOGFP, *fopen();
  219. char buff[BBUFSIZ];
  220. int nbchr;  /* number of chars read so far for buffered read */
  221.  
  222. int wason;
  223. int i_port, o_port;
  224. int catch;
  225.  
  226. int pagelen;
  227. char *ttyname();  /* forward declaration for C */
  228.  
  229. char *tty;
  230. char XMITTYPE;
  231. int ARPA, CMNDFLAG, RECVFLAG, SENDFLAG, FTP1, PMSG, DELFLAG, LOGFLAG, MUNGMODE;
  232. int STATDISP, BIT7, BITMASK, NOMUNGMODE;
  233. int delay, baud;
  234. char filename[256];
  235. char  abusy[35], bbusy[35]; /* names of lock files */
  236. alarmfunc();
  237.  
  238. main(argc, argv)
  239. int argc;
  240. char **argv;
  241. {
  242.         char *getenv();
  243.         char *getlogin();
  244.         char *fname = filename;
  245.         char *logfile;
  246.         int index, termstart();
  247.         char flag;
  248.  
  249.         logfile = "umodem.log";  /* Name of LOG File */
  250.         i_port = 0;        /* default input port */
  251.         o_port = 1;        /* default output port */
  252.  
  253.         printf("\nUMODEM Version %d.%d", VERSION/10, VERSION%10);
  254.         printf(" -- UNIX-Based Remote File Transfer Facility\n");
  255.  
  256.         if (argc < 2 || *argv[1] != '-')
  257.         {
  258.                 help(FALSE);
  259.                 exit(-1);
  260.         }
  261.  
  262.     baud = 1200;     /* default to 1200 baud terminal operation */
  263.         index = 1;  /* set index for loop */
  264.         delay = 3;  /* assume FTP 3 delay */
  265.         PMSG = FALSE;  /* turn off flags */
  266.         FTP1 = FALSE;  /* assume FTP 3 (CP/M UG XMODEM2) */
  267.         RECVFLAG = FALSE;  /* not receive */
  268.         SENDFLAG = FALSE;  /* not send either */
  269.         CMNDFLAG = FALSE;  /* not command either */
  270.         XMITTYPE = 't';  /* assume text */
  271.         DELFLAG = DELDEFAULT;
  272.         LOGFLAG = LOGDEFAULT;
  273.         if (LOGFLAG) LOGFLAG = TRUE;
  274.            else LOGFLAG = FALSE;  /* set LOGFLAG to REALLY true or false */
  275.         ARPA = FALSE;  /* assume not on ARPA Net */
  276.         MUNGMODE = FALSE; /* protect files from overwriting */
  277.         NOMUNGMODE = TRUE; /* keep user from using MUNGMODE */
  278.         if ((strcmp(getlogin(),"zeus"))==0) NOMUNGMODE = FALSE;
  279.         STATDISP = FALSE;  /* assume not a status display */
  280.         BIT7 = FALSE;  /* assume 8-bit communication */
  281.         while ((flag = argv[1][index++]) != '\0')
  282.             switch (flag) {
  283.                 case '1' : FTP1 = TRUE;  /* select FTP 1 */
  284.                            delay = 5;  /* FTP 1 delay constant */
  285.                            printf("\nUMODEM:  TERM II FTP 1 Selected\n");
  286.                            break;
  287.                 case '4' : FTP1 = TRUE;  /* select FTP 1 (varient) */
  288.                            BIT7 = TRUE;  /* transfer only 7 bits */
  289.                            delay = 5;  /* FTP 1 delay constant */
  290.                            printf("\nUMODEM:  TERM II FTP 4 Selected\n");
  291.                            break;
  292.                 case '7' : BIT7 = TRUE;  /* transfer only 7 bits */
  293.                            break;
  294.                 case 'a' : ARPA = TRUE;  /* set ARPA Net */
  295.                            break;
  296.                 case 'c' : CMNDFLAG = TRUE;  /* command mode */
  297.                            break;
  298.                 case 'd' : DELFLAG = !DELDEFAULT;  /* delete log file ? */
  299.                            break;
  300.                 case 'l' : LOGFLAG = !LOGDEFAULT;  /* turn off log ? */
  301.                            break;
  302.                 case 'm' : 
  303.                            if(NOMUNGMODE) break;
  304.                            MUNGMODE = TRUE; /* allow overwriting of files */
  305.                            break;
  306.                 case 'o' : 
  307.                termstart();     /* checks for two lock files */
  308.                if ((i_port = open(getenv("MODEM"), 2)) > 0) 
  309.                                 o_port = i_port;
  310.                            else
  311.                                 i_port = 0;
  312.                            if (i_port) {
  313.                                printf("\nCommunications to %s\n", 
  314.                                    ttyname(i_port));
  315.                                CMNDFLAG = TRUE; /* turn on command mode */
  316.                                printf("Entering local mode\n");
  317.                            }
  318.                 break;
  319.                 case 'p' : PMSG = TRUE;  /* print all messages */
  320.                            break;
  321.                 case 'r' : RECVFLAG = TRUE;  /* receive file */
  322.                            XMITTYPE = gettype(argv[1][index++]);  /* get t/b */
  323.                            break;
  324.                 case 's' : SENDFLAG = TRUE;  /* send file */
  325.                            XMITTYPE = gettype(argv[1][index++]);
  326.                            break;
  327.                 case 'y' : STATDISP = TRUE;  /* display file status */
  328.                            break;
  329.                 default  : error("Invalid Flag", FALSE);
  330.                 }
  331.  
  332.         if (BIT7 && (XMITTYPE == 'b'))
  333.         {  printf("\nUMODEM:  Fatal Error -- Both 7-Bit Transfer and ");
  334.            printf("Binary Transfer Selected");
  335.            exit(-1);  /* error exit to UNIX */
  336.         }
  337.  
  338.         if (BIT7)  /* set MASK value */
  339.            BITMASK = 0177;  /* 7 significant bits */
  340.         else
  341.            BITMASK = 0377;  /* 8 significant bits */
  342.  
  343.         if (PMSG)
  344.            { printf("\nSupported File Transfer Protocols:");
  345.              printf("\n\tTERM II FTP 1");
  346.              printf("\n\tCP/M UG XMODEM2 (TERM II FTP 3)");
  347.              printf("\n\tTERM II FTP 4");
  348.              printf("\n\n");
  349.            }
  350.  
  351.         if (CMNDFLAG) LOGFLAG = TRUE;  /* if command mode, always log */
  352.         if (LOGFLAG)
  353.            { 
  354.              if ((fname = getenv("HOME")) == 0) /* Get HOME variable */
  355.                 error("Can't get Environment!", FALSE);
  356.              fname = strcat(fname, "/");
  357.              fname = strcat(fname, logfile);
  358.              if (!DELFLAG)
  359.                 LOGFP = fopen(fname, "a");  /* append to LOG file */
  360.              else
  361.                 LOGFP = fopen(fname, "w");  /* new LOG file */
  362.              if (!LOGFP)
  363.                 error("Can't Open Log File", FALSE);
  364.              fprintf(LOGFP,"\n\n++++++++\n");
  365.              fprintf(LOGFP,"\nUMODEM Version %d.%d\n", VERSION/10, VERSION%10);
  366.              printf("\nUMODEM:  LOG File '%s' is Open\n", fname);
  367.            }
  368.  
  369.         if (STATDISP) {
  370.                 yfile(argv[2]);  /* status of a file */
  371.                 exit(0);  /* exit to UNIX */
  372.                 }
  373.  
  374.         if (RECVFLAG && SENDFLAG)
  375.                 error("Both Send and Receive Functions Specified", FALSE);
  376.         if (!RECVFLAG && !SENDFLAG && !CMNDFLAG)
  377.                 error("Send, Receive, or Command Functions NOT Given", FALSE);
  378.  
  379.         if (RECVFLAG)
  380.         {  if(open(argv[2], 0) != -1)  /* possible abort if file exists */
  381.            {    printf("\nUMODEM:  Warning -- Target File Exists\n");
  382.                 if( MUNGMODE == FALSE )
  383.                         error("Fatal - Can't overwrite file\n",FALSE);
  384.                 printf("UMODEM:  Overwriting Target File\n");
  385.            }
  386.            rfile(argv[2]);  /* receive file */
  387.         }
  388.         else {
  389.                 if (SENDFLAG) sfile(argv[2]);  /* send file */
  390.                 else command();  /* command mode */
  391.                 }
  392.         if (CMNDFLAG) LOGFLAG = TRUE;  /* for closing log file */
  393.         if (LOGFLAG) fclose(LOGFP);
  394.         exit(0);
  395. }
  396.  
  397. /*  Major Command Mode  */
  398. command()
  399. {
  400.         char cmd, *fname, *infile();
  401.         int command(), fpid, c;
  402.  
  403.         if (i_port) /* if local, then i_port is non-zero */
  404.                 signal(SIGINT, command);
  405.         printf("\nUMODEM Command Mode -- Type ? for Help");
  406.         do {
  407.            printf("\n");
  408.            printf(FTP1 ? "1" : "3");  /* FTP 1 or 3? */
  409.            printf(BIT7 ? "7" : " ");  /* BIT 7 or not? */
  410.            printf(ARPA ? "A" : " ");  /* ARPA Net or not? */
  411.            printf(LOGFLAG ? "L" : " ");  /* Log Entries or not? */
  412.            printf(MUNGMODE ? "M" : " ");  /* Mung Files or not? */
  413.            printf(" UMODEM> ");
  414.            scanf("%s", filename);
  415.            switch (cmd = (mklow(filename[0])&0177)) {
  416.                 case 't' : if (i_port==0) { /* only do it if local */
  417.                                 printf("Sorry, must be in local mode.\n");
  418.                                 break;
  419.                            }
  420.                            setmodes(baud);
  421.                            /* setup raw and noecho for console */
  422.                            gtty(0, &ttycon);
  423.                            gtty(0, &ttycom);
  424.                            ttycom.sg_flags |= RAW;
  425.                            ttycom.sg_flags &= ~ECHO;
  426.                            stty(0, &ttycom);
  427.                gtty(i_port, &ttystemp); /* get port parameters */
  428.                tty = ttyname(i_port);
  429.                stat(tty, &statbuf);
  430.                printf("\r\n");
  431.                prbaud(ttystemp.sg_ispeed);
  432.                printf("Modem port %s\r\n",tty);
  433.                printf("Hit Control G to Exit ... \r\n\n");
  434.                            if (!(fpid = fork())) { 
  435.                                 /* child to read from modem */
  436.                                 signal(SIGINT, SIG_DFL);
  437.                                 do {
  438.                                     if ((c=readbyte(0)) > 0)
  439.                                         conout(c);
  440.                                 } while(1);
  441.                            } else {
  442.                                 /* parent, reading from console */
  443.                                 while ((c=conin()) != 'G'-0x40)
  444.                                     sendbyte(c);
  445.                                 kill(fpid, 2);
  446.                            }
  447.                            /* put it back the way you got it */
  448.                            stty(0, &ttycon);
  449.                            printf("\n\nExiting terminal mode\n\n");
  450.                            break;
  451.                 case '1' : FTP1 = TRUE;  /* select FTP 1 */
  452.                            delay = 5;  /* FTP 1 delay constant */
  453.                            printf("\nTERM FTP 1 Selected");
  454.                            break;
  455.                 case '3' : FTP1 = FALSE; /* select FTP 3 */
  456.                            delay = 3;  /* FTP 3 delay constant */
  457.                            printf("\nTERM FTP 3 Selected");
  458.                            break;
  459.                 case '7' : BIT7 = ~BIT7;  /* toggle 7 bit transfer */
  460.                            printf("\n7-Bit Transfer %s Selected",
  461.                                 BIT7 ? "" : "NOT");
  462.                            break;
  463.                 case 'a' : ARPA = ~ARPA;  /* toggle ARPA Net */
  464.                            printf("\nDDN Interface %s Selected",
  465.                                 ARPA ? "" : "NOT");
  466.                            break;
  467.                 case 'l' : LOGFLAG = ~LOGFLAG;  /* toggle log flag */
  468.                            printf("\nEntry Logging %s Enabled",
  469.                                 LOGFLAG ? "" : "NOT");
  470.                            break;
  471.                 case 'm' : 
  472.                            if(NOMUNGMODE)
  473.                            {
  474.                            printf("\nOverwrite Permission Denied");
  475.                            break;
  476.                            }
  477.                            MUNGMODE = ~MUNGMODE; /* toggle file overwrite */
  478.                            printf("\nFile Overwriting %s Enabled",
  479.                                 MUNGMODE ? "" : "NOT");
  480.                            break;
  481.                 case 'r' : RECVFLAG = TRUE;  /* receive file */
  482.                            XMITTYPE = mklow(filename[1]);
  483.                            fname = infile();  /* get file name */
  484.                            if (*fname != '\0') 
  485.                               {  if(open(fname, 0) != -1)
  486.                                  {
  487.                           printf("\nUMODEM:  Warning -- Target File Exists\n");
  488.                                     if( MUNGMODE == FALSE )
  489.                                       {
  490.                                       printf("Fatal - Can't overwrite file\n");
  491.                                       break;
  492.                                       }
  493.                                   printf("UMODEM:  Overwriting Target File\n");
  494.                                   }
  495.                                  rfile(fname);
  496.                               }
  497.                            break;
  498.                 case 's' : SENDFLAG = TRUE;  /* send file */
  499.                            XMITTYPE = mklow(filename[1]);
  500.                            fname = infile();  /* get file name */
  501.                            if (*fname != '\0') sfile(fname);
  502.                            break;
  503.                 case 'x' : if(i_port != 0){
  504.                 close(i_port);
  505.                 unlink (abusy);
  506.                 unlink (bbusy);
  507.                }
  508.                exit(0); /* hard core exit */
  509.                 case 'y' : fname = infile();  /* get file name */
  510.                            if (*fname != '\0') yfile(fname);
  511.                            break;
  512.         case 'b' : printf("Baud rate is now %d. Change? ",baud);
  513.                scanf("%s",filename);
  514.                printf("\r\n");
  515.                cmd = mklow(filename[0] & 0177);
  516.                if (cmd == 'y'){
  517.                 if (baud == 1200)
  518.                     baud = 300;
  519.                 else baud = 1200;
  520.                 }
  521.                break;
  522.                 default  : help(TRUE);
  523.            }
  524.         } while (cmd != 'x');
  525. }
  526.  
  527. /*  Get file name from user  */
  528. char *infile()
  529. {
  530.         char *startptr = filename;
  531.  
  532.         scanf("%s",startptr);
  533.         if (*startptr == '.') *startptr = '\0';  /* set NULL */
  534.         return(startptr);
  535. }
  536.  
  537. /*  Print Help Message  */
  538. help(caller)
  539. int caller;
  540. {
  541.         if (!caller) { printf("\nUsage:  \n\tumodem ");
  542.                 printf("-[o!c!rb!rt!sb!st][options]");
  543.                 printf(" filename\n");
  544.                 }
  545.         else {
  546.                 printf("\nUsage: r or s or option");
  547.                 }
  548.         printf("\nMajor Commands --");
  549.         if (!caller) printf("\n\tc  <-- Enter Command Mode");
  550.         printf("\n\trb <-- Receive Binary");
  551.         printf("\n\trt <-- Receive Text");
  552.         printf("\n\tsb <-- Send Binary");
  553.         printf("\n\tst <-- Send Text");
  554.         printf("\nOptions --");
  555.         printf("\n\t1  <-- (one) Employ TERM II FTP 1");
  556.         if (caller) printf("\n\t3  <-- Enable TERM FTP 3 (CP/M UG)");
  557.         if (!caller) printf("\n\t4  <-- Enable TERM FTP 4");
  558.         printf("\n\t7  <-- Enable 7-bit transfer mask");
  559.         printf("\n\ta  <-- Turn ON ARPA Net Flag");
  560.     printf("\n\tt  <-- Enter terminal mode (if enabled)");
  561.     printf("\n\tb  <-- Toggle 1200/300 baud for terminal");
  562.         if (!caller)
  563. #if DELDEFAULT == 1
  564.         printf("\n\td  <-- Do not delete umodem.log file before starting");
  565. #else
  566.         printf("\n\td  <-- Delete umodem.log file before starting");
  567. #endif
  568.  
  569.         if (!caller)
  570. #if LOGDEFAULT == 1
  571.         printf("\n\tl  <-- (ell) Turn OFF LOG File Entries");
  572. #else
  573.         printf("\n\tl  <-- (ell) Turn ON LOG File Entries");
  574. #endif
  575.         else printf("\n\tl  <-- Toggle LOG File Entries");
  576.  
  577.         printf("\n\tm  <-- Allow file overwiting on receive");
  578.         if (!caller) printf("\n\tp  <-- Turn ON Parameter Display");
  579.         if (!caller) printf("\n\to  <-- Enable terminal mode ");
  580.         if (caller) printf("\n\tx  <-- Exit");
  581.         printf("\n\ty  <-- Display file status (size) information only");
  582.         printf("\n");
  583. }
  584.  
  585. gettype(ichar)
  586. char ichar;
  587. {
  588.         if (ichar == 't') return(ichar);
  589.         if (ichar == 'b') return(ichar);
  590.         error("Invalid Send/Receive Parameter - not t or b", FALSE);
  591.         return;
  592. }
  593.  
  594. /* set tty modes for UMODEM transfers */
  595. setmodes(b)
  596. int b;
  597. {
  598.  
  599.  
  600.         /* changed to get tty params from working console, so that
  601.            other mode changes would not interfere. */
  602.         if (gtty(0, &ttys) < 0)  /* get current tty params */
  603.                 error("Can't get TTY Parameters", TRUE);
  604.         tty = ttyname(i_port);  /* identify current tty */
  605.         /* transfer current modes to new structure */
  606.         if (!i_port) {
  607.                 ttysnew.sg_ispeed = ttys.sg_ispeed;     /* copy input speed */
  608.                 ttysnew.sg_ospeed = ttys.sg_ospeed;     /* copy output speed */
  609.         } 
  610.     else if (b == 1200){
  611.                 ttysnew.sg_ispeed = B1200;
  612.                 ttysnew.sg_ospeed = B1200;
  613.         }
  614.     else {
  615.         ttysnew.sg_ispeed = B300;
  616.         ttysnew.sg_ospeed = B300;
  617.     }
  618.         ttysnew.sg_erase  = ttys.sg_erase;      /* copy erase flags */
  619.         ttysnew.sg_flags  = ttys.sg_flags;      /* copy flags */
  620.         ttysnew.sg_kill   = ttys.sg_kill;       /* copy std terminal flags */
  621.         
  622.  
  623.         ttysnew.sg_flags |= RAW;    /* set for RAW Mode */
  624.                         /* This ORs in the RAW mode value, thereby
  625.                            setting RAW mode and leaving the other
  626.                            mode settings unchanged */
  627.         ttysnew.sg_flags &= ~ECHO;  /* set for no echoing */
  628.                         /* This ANDs in the complement of the ECHO
  629.                            setting (for NO echo), thereby leaving all
  630.                            current parameters unchanged and turning
  631.                            OFF ECHO only */
  632.         ttysnew.sg_flags &= ~XTABS;  /* set for no tab expansion */
  633.         ttysnew.sg_flags &= ~LCASE;  /* set for no upper-to-lower case xlate */
  634.         ttysnew.sg_flags |= ANYP;  /* set for ANY Parity */
  635.         ttysnew.sg_flags &= ~NL3;  /* turn off ALL delays - new line */
  636.         ttysnew.sg_flags &= ~TAB0; /* turn off tab delays */
  637.         ttysnew.sg_flags &= ~TAB1;
  638.         ttysnew.sg_flags &= ~CR3;  /* turn off CR delays */
  639.         ttysnew.sg_flags &= ~FF1;  /* turn off FF delays */
  640.         ttysnew.sg_flags &= ~BS1;  /* turn off BS delays */
  641.  
  642.         if (stty(i_port, &ttysnew) < 0)  /* set new params */
  643.                 error("Can't set new TTY Parameters", TRUE);
  644.  
  645.         if (stat(tty, &statbuf) < 0)  /* get tty status */ 
  646.                 error("Can't get your TTY Status", TRUE);
  647.  
  648.         if (PMSG)
  649.                 { printf("\nUMODEM:  TTY Device Parameters Altered");
  650.                   ttyparams();  /* print tty params */
  651.                 }
  652.  
  653.         if (ARPA)  /* set 8-bit on ARPA Net */
  654.                 setarpa();
  655.  
  656.         return;
  657. }
  658.  
  659. /*  set ARPA Net for 8-bit transfers  */
  660. setarpa()
  661. {
  662.         sendbyte(IAC);  /* Is A Command */
  663.         sendbyte(WILL); /* Command to SERVER TELNET (Host) */
  664.         sendbyte(TRBIN);        /* Command is:  Transmit Binary */
  665.  
  666.         sendbyte(IAC);  /* Is A Command */
  667.         sendbyte(DO);   /* Command to TIP */
  668.         sendbyte(TRBIN);        /* Command is:  Transmit Binary */
  669.  
  670.         sleep(3);  /* wait for TIP to configure */
  671.  
  672.         return;
  673. }
  674.  
  675. /* restore normal tty modes */
  676. restoremodes(errcall)
  677. int errcall;
  678. {
  679.         if (ARPA)  /* if ARPA Net, reconfigure */
  680.                 resetarpa();
  681.  
  682.  
  683.         if (stty(i_port, &ttys) < 0)  /* restore original tty modes */
  684.                 { if (!errcall)
  685.                    error("RESET - Can't restore normal TTY Params", FALSE);
  686.                 else
  687.                    { printf("UMODEM:  ");
  688.                      printf("RESET - Can't restore normal TTY Params\n");
  689.                    }
  690.                 }
  691.  
  692.         if (PMSG)
  693.                 { printf("\nUMODEM:  TTY Device Parameters Restored");
  694.                   ttyparams();  /* print tty params */
  695.                 }
  696.  
  697.         return;
  698. }
  699.  
  700. /* reset the ARPA Net */
  701. resetarpa()
  702. {
  703.         sendbyte(IAC);  /* Is A Command */
  704.         sendbyte(WONT); /* Negative Command to SERVER TELNET (Host) */
  705.         sendbyte(TRBIN);        /* Command is:  Don't Transmit Binary */
  706.  
  707.         sendbyte(IAC);  /* Is A Command */
  708.         sendbyte(DONT); /* Negative Command to TIP */
  709.         sendbyte(TRBIN);        /* Command is:  Don't Transmit Binary */
  710.  
  711.         return;
  712. }
  713.  
  714. /* print error message and exit; if mode == TRUE, restore normal tty modes */
  715. error(msg, mode)
  716. char *msg;
  717. int mode;
  718. {
  719.         if (mode)
  720.                 restoremodes(TRUE);  /* put back normal tty modes */
  721.         printf("UMODEM:  %s\n", msg);
  722.         if (LOGFLAG & (int)LOGFP)
  723.         {   fprintf(LOGFP, "UMODEM Fatal Error:  %s\n", msg);
  724.             fclose(LOGFP);
  725.         }
  726.         exit(-1);
  727. }
  728.  
  729. /**  print status (size) of a file  **/
  730. yfile(name)
  731. char *name;
  732. {
  733.         printf("\nUMODEM File Status Display for %s\n", name);
  734.  
  735.         if (open(name,0) < 0) {
  736.                 printf("File %s does not exist\n", name);
  737.                 return;
  738.                 }
  739.  
  740.         prfilestat(name);  /* print status */
  741.         printf("\n");
  742. }
  743.  
  744. getbyte(fildes, ch)                             /* Buffered disk read */
  745. int fildes;
  746. char *ch;
  747. /*
  748.  *
  749.  *      Get a byte from the specified file.  Buffer the read so we don't
  750.  *      have to use a system call for each character.
  751.  *
  752.  */
  753.  
  754. {
  755.         static char buf[BUFSIZ];        /* Remember buffer */
  756.         static char *bufp = buf;        /* Remember where we are in buffer */
  757.         
  758.         if (nbchr == 0)                 /* Buffer exausted; read some more */
  759.         {
  760.                 if ((nbchr = read(fildes, buf, BUFSIZ)) < 0)
  761.                         error("File Read Error", TRUE);
  762.                 bufp = buf;             /* Set pointer to start of array */
  763.         }
  764.         if (--nbchr >= 0)
  765.         {
  766.                 *ch = *bufp++;
  767.                 return(0);
  768.         }
  769.         else
  770.                 return(EOF);
  771. }
  772.  
  773. /**  receive a file  **/
  774. rfile(name)
  775. char *name;
  776. {
  777.         char mode;
  778.         int fd, j, firstchar, sectnum, sectcurr, tmode;
  779.         int sectcomp, errors, errorflag, recfin;
  780.         register int bufctr, checksum;
  781.         register int c;
  782.         int errorchar, fatalerror, startstx, inchecksum, endetx, endenq;
  783.         long recvsectcnt;
  784.  
  785.         mode = XMITTYPE;  /* set t/b mode */
  786.         if ((fd = creat(name, CREATMODE)) < 0)
  787.                 error("Can't create file for receive", FALSE);
  788.         setmodes(baud);  /* setup tty modes for xfer */
  789.         printf("\r\nUMODEM:  File Name: %s", name);
  790.         if (LOGFLAG)
  791.         {    fprintf(LOGFP, "\n----\nUMODEM Receive Function\n");
  792.              fprintf(LOGFP, "File Name: %s\n", name);
  793.              if (FTP1)
  794.                 if (!BIT7)
  795.                  fprintf(LOGFP, "TERM II File Transfer Protocol 1 Selected\n");
  796.                 else
  797.                  fprintf(LOGFP, "TERM II File Transfer Protocol 4 Selected\n");
  798.              else
  799.                 fprintf(LOGFP,
  800.                   "TERM II File Transfer Protocol 3 (CP/M UG) Selected\n");
  801.              if (BIT7)
  802.                 fprintf(LOGFP, "7-Bit Transmission Enabled\n");
  803.              else
  804.                 fprintf(LOGFP, "8-Bit Transmission Enabled\n");
  805.         }
  806.         printf("\r\nUMODEM:  ");
  807.         if (BIT7)
  808.                 printf("7-Bit");
  809.         else
  810.                 printf("8-Bit");
  811.         printf(" Transmission Enabled");
  812.         printf("\r\nUMODEM:  Ready to RECEIVE File\r\n");
  813.  
  814.         recfin = FALSE;
  815.         sectnum = errors = 0;
  816.         fatalerror = FALSE;  /* NO fatal errors */
  817.         recvsectcnt = 0;  /* number of received sectors */
  818.  
  819.         if (mode == 't')
  820.                 tmode = TRUE;
  821.         else
  822.                 tmode = FALSE;
  823.  
  824.         if (tmode && i_port)
  825.                 printf("\n\rText mode conversions activated (cp/m files)\n\r");
  826.  
  827.         if (i_port)
  828.                 printf("\nSync...\n\n");
  829.         if (FTP1)
  830.         {
  831.           while (readbyte(4) != SYN);
  832.           sendbyte(ACK);  /* FTP 1 Sync */
  833.         }
  834.         else sendbyte(NAK);  /* FTP 3 Sync */
  835.  
  836.         do
  837.         {   errorflag = FALSE;
  838.             do {
  839.                   firstchar = readbyte(6);
  840.             } while ((firstchar != SOH) && (firstchar != EOT) && (firstchar 
  841.                      != TIMEOUT));
  842.             if (firstchar == TIMEOUT)
  843.             {  if (LOGFLAG)
  844.                 fprintf(LOGFP, "Timeout on Sector %d\n", sectnum);
  845.                errorflag = TRUE;
  846.             }
  847.  
  848.             if (firstchar == SOH)
  849.             {  if (FTP1) readbyte(5);  /* discard leading zero */
  850.                sectcurr = readbyte(delay);
  851.                sectcomp = readbyte(delay);
  852.                if (FTP1) startstx = readbyte(delay);  /* get leading STX */
  853.                if ((sectcurr + sectcomp) == BITMASK)
  854.                {  if (sectcurr == ((sectnum+1)&BITMASK))
  855.                   {  checksum = 0;
  856.                      for (j = bufctr = 0; j < BBUFSIZ; j++)
  857.                      {  buff[bufctr] = c = readbyte(delay);
  858.                         checksum = ((checksum+c)&BITMASK);
  859.                         if (!tmode)  /* binary mode */
  860.                         {  bufctr++;
  861.                            continue;
  862.                         }
  863.                         if (c == CR)
  864.                            continue;  /* skip CR's */
  865.                         if (c == CTRLZ)  /* skip CP/M EOF char */
  866.                         {  recfin = TRUE;  /* flag EOF */
  867.                            continue;
  868.                         }
  869.                         if (!recfin)
  870.                            bufctr++;
  871.                      }
  872.                      if (FTP1) endetx = readbyte(delay);  /* get ending ETX */
  873.                      inchecksum = readbyte(delay);  /* get checksum */
  874.                      if (FTP1) endenq = readbyte(delay); /* get ENQ */
  875.                      if (checksum == inchecksum)  /* good checksum */
  876.                      {  errors = 0;
  877.                         recvsectcnt++;
  878.                         sectnum = sectcurr;  /* update sector counter */
  879.                         if (write(fd, buff, bufctr) < 0)
  880.                            error("File Write Error", TRUE);
  881.                         else
  882.                         {  
  883.                            if (i_port)
  884.                                 fprintf(stderr, "Received Sector %d   \r", sectcurr);
  885.                             if (FTP1) sendbyte(ESC);  /* FTP 1 requires <ESC> */
  886.                            sendbyte(ACK);
  887.                         }
  888.                      }
  889.                      else
  890.                      {  if (LOGFLAG)
  891.                           fprintf(LOGFP, "Checksum Error on Sector %d   \n",
  892.                                 sectnum);
  893.                           errorflag = TRUE;
  894.                      }
  895.                   }
  896.                   else
  897.                   { if (sectcurr == sectnum)
  898.                     {  while(readbyte(3) != TIMEOUT);
  899.                        if (FTP1) sendbyte(ESC);  /* FTP 1 requires <ESC> */
  900.                        sendbyte(ACK);
  901.                     }
  902.                     else
  903.                     {  if (LOGFLAG)
  904.                         { fprintf(LOGFP, "Phase Error - Received Sector is ");
  905.                           fprintf(LOGFP, "%d while Expected Sector is %d\n",
  906.                            sectcurr, ((sectnum+1)&BITMASK));
  907.                         }
  908.                         errorflag = TRUE;
  909.                         fatalerror = TRUE;
  910.                         if (FTP1) sendbyte(ESC);  /* FTP 1 requires <ESC> */
  911.                         sendbyte(CAN);
  912.                     }
  913.                   }
  914.            }
  915.            else
  916.            {  if (LOGFLAG)
  917.                 fprintf(LOGFP, "Header Sector Number Error on Sector %d\n",
  918.                    sectnum);
  919.                errorflag = TRUE;
  920.            }
  921.         }
  922.         if (FTP1 && !errorflag)
  923.         {  if (startstx != STX)
  924.            {  errorflag = TRUE;  /* FTP 1 STX missing */
  925.               errorchar = STX;
  926.            }
  927.            if (endetx != ETX)
  928.            {  errorflag = TRUE;  /* FTP 1 ETX missing */
  929.               errorchar = ETX;
  930.            }
  931.            if (endenq != ENQ)
  932.            {  errorflag = TRUE;  /* FTP 1 ENQ missing */
  933.               errorchar = ENQ;
  934.            }
  935.            if (errorflag && LOGFLAG)
  936.            {  fprintf(LOGFP, "Invalid Packet-Control Character:  ");
  937.               switch (errorchar) {
  938.                 case STX : fprintf(LOGFP, "STX"); break;
  939.                 case ETX : fprintf(LOGFP, "ETX"); break;
  940.                 case ENQ : fprintf(LOGFP, "ENQ"); break;
  941.                 default  : fprintf(LOGFP, "Error"); break;
  942.               }
  943.               fprintf(LOGFP, "\n");
  944.            }
  945.         }
  946.         if (errorflag == TRUE)
  947.         {  errors++;
  948.            while (readbyte(3) != TIMEOUT);
  949.            sendbyte(NAK);
  950.         }
  951.   }
  952.   while ((firstchar != EOT) && (errors != ERRORMAX) && !fatalerror);
  953.   if ((firstchar == EOT) && (errors < ERRORMAX))
  954.   {  if (!FTP1) sendbyte(ACK);
  955.      close(fd);
  956.      restoremodes(FALSE);  /* restore normal tty modes */
  957.      if (FTP1)
  958.         while (readbyte(3) != TIMEOUT);  /* flush EOT's */
  959.      sleep(3);  /* give other side time to return to terminal mode */
  960.      if (LOGFLAG)
  961.      {  fprintf(LOGFP, "\nReceive Complete\n");
  962.         fprintf(LOGFP,"Number of Received CP/M Records is %ld\n", recvsectcnt);
  963.      }
  964.      printf("\n");
  965.   }
  966.   else
  967.   {  if (LOGFLAG && FTP1 && fatalerror) fprintf(LOGFP,
  968.         "Synchronization Error");
  969.      error("TIMEOUT -- Too Many Errors", TRUE);
  970.   }
  971. }
  972.  
  973. /**  send a file  **/
  974. sfile(name)
  975. char *name;
  976. {
  977.         char mode, c;
  978.         int fd, attempts, nlflag, sendfin, tmode, sendresp;
  979.         register int bufctr, checksum, sectnum;
  980.  
  981.         nbchr = 0;  /* clear buffered read char count */
  982.         mode = XMITTYPE;  /* set t/b mode */
  983.         if ((fd = open(name, 0)) < 0)
  984.         {  if (LOGFLAG) fprintf(LOGFP, "Can't Open File\n");
  985.            error("Can't open file for send", FALSE);
  986.         }
  987.         setmodes(baud);  /* setup tty modes for xfer */     
  988.         printf("\r\nUMODEM:  File Name: %s", name);
  989.         if (LOGFLAG)
  990.         {   fprintf(LOGFP, "\n----\nUMODEM Send Function\n");
  991.             fprintf(LOGFP, "File Name: %s\n", name);
  992.         }
  993.         printf("\r\n"); prfilestat(name);  /* print file size statistics */
  994.         if (LOGFLAG)
  995.         {  if (FTP1)
  996.               if (!BIT7)
  997.                 fprintf(LOGFP, "TERM II File Transfer Protocol 1 Selected\n");
  998.               else
  999.                 fprintf(LOGFP, "TERM II File Transfer Protocol 4 Selected\n");
  1000.            else
  1001.                 fprintf(LOGFP,
  1002.                    "TERM II File Transfer Protocol 3 (CP/M UG) Selected\n");
  1003.            if (BIT7)
  1004.                 fprintf(LOGFP, "7-Bit Transmission Enabled\n");
  1005.            else
  1006.                 fprintf(LOGFP, "8-Bit Transmission Enabled\n");
  1007.         }
  1008.         printf("\r\nUMODEM:  ");
  1009.         if (BIT7)
  1010.                 printf("7-Bit");
  1011.         else
  1012.                 printf("8-Bit");
  1013.         printf(" Transmission Enabled");
  1014.         printf("\r\nUMODEM:  Ready to SEND File\r\n");
  1015.  
  1016.         if (mode == 't')
  1017.            tmode = TRUE;
  1018.         else
  1019.            tmode = FALSE;
  1020.  
  1021.         if (tmode && i_port)
  1022.                 printf("\n\rText mode conversions activated (cp/m files)\n\r");
  1023.         sendfin = nlflag = FALSE;
  1024.         attempts = 0;
  1025.  
  1026.         if (i_port)
  1027.                 printf("\nSync...\n\n");
  1028.         if (FTP1)
  1029.         {  sendbyte(SYN);  /* FTP 1 Synchronize with Receiver */
  1030.            while (readbyte(5) != ACK)
  1031.            {  if(++attempts > RETRYMAX*6) error("Remote System Not Responding",
  1032.                 TRUE);
  1033.               sendbyte(SYN);
  1034.            }
  1035.         }
  1036.         else
  1037.         {  while (readbyte(30) != NAK)  /* FTP 3 Synchronize with Receiver */
  1038.            if (++attempts > RETRYMAX) error("Remote System Not Responding",
  1039.                 TRUE);
  1040.         }
  1041.  
  1042.         sectnum = 1;  /* first sector number */
  1043.         attempts = 0;
  1044.  
  1045.         do 
  1046.         {   for (bufctr=0; bufctr < BBUFSIZ;)
  1047.             {   if (nlflag)
  1048.                 {  buff[bufctr++] = LF;  /* leftover newline */
  1049.                    nlflag = FALSE;
  1050.                 }
  1051.                 if (getbyte(fd, &c) == EOF)
  1052.                 {  sendfin = TRUE;  /* this is the last sector */
  1053.                    if (!bufctr)  /* if EOF on sector boundary */
  1054.                       break;  /* avoid sending extra sector */
  1055.                    if (tmode)
  1056.                       buff[bufctr++] = CTRLZ;  /* Control-Z for CP/M EOF */
  1057.                    else
  1058.                       buff[bufctr++] = ZERO;
  1059.                    continue;
  1060.                 }
  1061.                 if (tmode && c == LF)  /* text mode & Unix newline? */
  1062.                 {  if (c == LF)  /* Unix newline? */
  1063.                    {  buff[bufctr++] = CR;  /* insert carriage return */
  1064.                       if (bufctr < BBUFSIZ)
  1065.                          buff[bufctr++] = LF;  /* insert Unix newline */
  1066.                       else
  1067.                          nlflag = TRUE;  /* insert newline on next sector */
  1068.                    }
  1069.                    continue;
  1070.                 }       
  1071.                 buff[bufctr++] = c;  /* copy the char without change */
  1072.             }
  1073.             attempts = 0;
  1074.         
  1075.             if (!bufctr)  /* if EOF on sector boundary */
  1076.                break;  /* avoid sending empty sector */
  1077.  
  1078.             do
  1079.             {   
  1080.                 if (i_port)
  1081.                         fprintf(stderr, "Sending Sector %d   \r", sectnum);
  1082.                 sendbyte(SOH);  /* send start of packet header */
  1083.                 if (FTP1) sendbyte(0);  /* FTP 1 Type 0 Packet */
  1084.                 sendbyte(sectnum);  /* send current sector number */
  1085.                 sendbyte(-sectnum-1);  /* and its complement */
  1086.                 if (FTP1) sendbyte(STX);  /* send STX */
  1087.                 checksum = 0;  /* init checksum */
  1088.                 for (bufctr=0; bufctr < BBUFSIZ; bufctr++)
  1089.                 {  sendbyte(buff[bufctr]);  /* send the byte */
  1090.                    if (ARPA && (buff[bufctr]==0xff))  /* ARPA Net FFH esc */
  1091.                         sendbyte(buff[bufctr]);  /* send 2 FFH's for one */
  1092.                    checksum = ((checksum+buff[bufctr])&BITMASK);
  1093.                 }
  1094. /*              while (readbyte(3) != TIMEOUT);   flush chars from line */
  1095.                 if (FTP1) sendbyte(ETX);  /* send ETX */
  1096.                 sendbyte(checksum);  /* send the checksum */
  1097.                 if (FTP1) sendbyte(ENQ);  /* send ENQ */
  1098.                 attempts++;
  1099.                 if (FTP1)
  1100.                 {  sendresp = NAK;  /* prepare for NAK */
  1101.                    if (readbyte(10) == ESC) sendresp = readbyte(10);
  1102.                 }
  1103.                 else
  1104.                    sendresp = readbyte(10);  /* get response */
  1105.                 if ((sendresp != ACK) && LOGFLAG)
  1106.                    { fprintf(LOGFP, "Non-ACK Received on Sector %d   \n",
  1107.                       sectnum);
  1108.                      if (sendresp == TIMEOUT)
  1109.                         fprintf(LOGFP, "This Non-ACK was a TIMEOUT\n");
  1110.                    }
  1111.             }   while((sendresp != ACK) && (attempts != RETRYMAX));
  1112.             sectnum++;  /* increment to next sector number */
  1113.     }  while (!sendfin && (attempts != RETRYMAX));
  1114.  
  1115.     if (attempts == RETRYMAX)
  1116.         error("Remote System Not Responding", TRUE);
  1117.  
  1118.     attempts = 0;
  1119.     if (FTP1)
  1120.         while (attempts++ < 10) sendbyte(EOT);
  1121.     else
  1122.     {   sendbyte(EOT);  /* send 1st EOT */
  1123.         while ((readbyte(15) != ACK) && (attempts++ < RETRYMAX))
  1124.            sendbyte(EOT);
  1125.         if (attempts >= RETRYMAX)
  1126.            error("Remote System Not Responding on Completion", TRUE);
  1127.     }
  1128.  
  1129.     close(fd);
  1130.     restoremodes(FALSE);  
  1131.     sleep(5);  /* give other side time to return to terminal mode */
  1132.     if (LOGFLAG)
  1133.     {  fprintf(LOGFP, "\nSend Complete\n");
  1134.     }
  1135.     printf("\n");
  1136.  
  1137. }
  1138.  
  1139. /*  print file size status information  */
  1140. prfilestat(name)
  1141. char *name;
  1142. {
  1143.         struct stat filestatbuf; /* file status info */
  1144.  
  1145.         stat(name, &filestatbuf);  /* get file status bytes */
  1146.         printf("  Estimated File Size %ldK, %ld Records, %ld Bytes",
  1147.           (filestatbuf.st_size/1024)+1, (filestatbuf.st_size/128)+1,
  1148.           filestatbuf.st_size);
  1149.         if (LOGFLAG)
  1150.           fprintf(LOGFP,"Estimated File Size %ldK, %ld Records, %ld Bytes\n",
  1151.           (filestatbuf.st_size/1024)+1, (filestatbuf.st_size/128)+1,
  1152.           filestatbuf.st_size);
  1153.         return;
  1154. }
  1155.  
  1156. /* get a byte from data stream -- timeout if "seconds" elapses */
  1157. readbyte(seconds)
  1158. unsigned seconds;
  1159. {
  1160.         char c;
  1161.         
  1162.         signal(SIGALRM,alarmfunc);  /* catch alarms */  
  1163.         alarm(seconds);  /* set the alarm clock */
  1164.         if (read(i_port, &c, 1) < 0)  /* get a char; error means we timed out */
  1165.           {
  1166.              return(TIMEOUT);
  1167.           }
  1168.         alarm(0);  /* turn off the alarm */
  1169.         return((c&BITMASK));  /* return the char */
  1170. }
  1171.  
  1172. /* send a byte to data stream */
  1173. sendbyte(data)
  1174. char data;
  1175. {
  1176.         char dataout;
  1177.         dataout = (data&BITMASK);  /* mask for 7 or 8 bits */
  1178.         write(o_port, &dataout, 1);  /* write the byte */
  1179.         return;
  1180. }
  1181.  
  1182. /* function for alarm clock timeouts */
  1183. alarmfunc()
  1184. {
  1185.         return;  /* this is basically a dummy function to force error */
  1186.                  /* status return on the "read" call in "readbyte"    */
  1187. }
  1188.  
  1189. /* print data on TTY setting */
  1190. ttyparams()
  1191. {
  1192.         
  1193.         gtty(i_port, &ttystemp);  /* get current tty params */
  1194.  
  1195.         tty = ttyname(i_port);  /* get name of tty */
  1196.         stat(tty, &statbuf);  /* get more tty params */
  1197.  
  1198.           printf("\r\n\nModem Port Parameter Display");
  1199.           printf("\r\n\tTTY Device Name is %s\r\n\n", tty);
  1200.           printf("\tAny Parity Allowed "); pryn(ANYP);
  1201.           printf("\tEven Parity Allowed"); pryn(EVENP);
  1202.           printf("\tOdd Parity Allowed "); pryn(ODDP);
  1203.           printf("\tEcho Enabled       "); pryn(ECHO);
  1204.           printf("\tLower Case Map     "); pryn(LCASE);
  1205.           printf("\tTabs Expanded      "); pryn(XTABS);
  1206.           printf("\tCR Mode Enabled    "); pryn(CRMOD);
  1207.           printf("\tRAW Mode Enabled   "); pryn(RAW);
  1208.  
  1209.           printf("\tTTY Input Rate     :   ");
  1210.             prbaud(ttystemp.sg_ispeed);
  1211.           printf("\tTTY Output Rate    :   ");
  1212.             prbaud(ttystemp.sg_ospeed);  /* print output baud rate */
  1213. }
  1214.  
  1215. pryn(iflag)
  1216. int iflag;
  1217. {
  1218.  
  1219.         if (ttystemp.sg_flags&iflag)
  1220.  
  1221.            printf(":   Yes\r\n");
  1222.         else
  1223.            printf(":   No\r\n");
  1224. }
  1225.  
  1226.  
  1227. prbaud(speed)
  1228. char speed;
  1229. {
  1230.         switch (speed) {
  1231.  
  1232.                 case B75 : printf("75"); break;
  1233.                 case B110 : printf("110"); break;
  1234.                 case B134 : printf("134.5"); break;
  1235.                 case B150 : printf("150"); break;
  1236.                 case B200 : printf("200"); break;
  1237.                 case B300 : printf("300"); break;
  1238.                 case B600 : printf("600"); break;
  1239.                 case B1200 : printf("1200"); break;
  1240.                 case B1800 : printf("1800"); break;
  1241.                 case B2400 : printf("2400"); break;
  1242.                 case B4800 : printf("4800"); break;
  1243.                 case B9600 : printf("9600"); break;
  1244.                 default : printf("Error");break;
  1245.         }
  1246.         printf(" Baud\r\n");
  1247. }
  1248.  
  1249.  
  1250. termstart()
  1251. {
  1252.     int k,i;
  1253.     FILE *bp;
  1254.     char *getenv();
  1255.     char filnm[30];
  1256.  
  1257.     strcpy (bbusy, getenv("MODEM"));
  1258.     for(i=0; bbusy[i+3]; ++i)
  1259.     {
  1260.         if (bbusy[i] != 'd')
  1261.             continue;
  1262.         if (bbusy[i] != 'e')
  1263.             continue;
  1264.         if (bbusy[i] != 'v')
  1265.             continue;
  1266.         if (bbusy[i] != '/')
  1267.             continue;
  1268.         k=0;
  1269.         while (bbusy[i]){
  1270.             filnm[k] = bbusy[i];
  1271.             ++i;
  1272.             ++k;
  1273.             }
  1274.         filnm[k] = 0;
  1275.         strcpy (bbusy, "/usr/spool/uucp/LCK..");
  1276.         strcat (bbusy, filnm);
  1277.         if ((bp=fopen(bbusy,"r")) == NULL)
  1278.         {
  1279.             if((bp=fopen(bbusy,"w")) == NULL)
  1280.             {
  1281.                printf("Can't open uucp lock file %s\n", bbusy);
  1282.                exit (-1);
  1283.             }
  1284.             fclose(bp);
  1285.             i=438;
  1286.             chmod(bbusy,i);
  1287.         }
  1288.         else
  1289.         {
  1290.             printf("uucp lock file is present! Try later.\n");
  1291.             exit(-1);
  1292.         }
  1293.     }
  1294.     return;
  1295. }
  1296. conin()
  1297. {
  1298. char c;
  1299. read(0, &c, 1);
  1300. c=c&127;
  1301. return(c);
  1302. }
  1303. conout(c)
  1304. char c;
  1305. {
  1306. c = c&127;
  1307. write (1,&c,1);
  1308. }
  1309.  
  1310.